package wrap

import (
	"excel-handle/ent"
	"excel-handle/ent/enum"
	"excel-handle/ent/json"
	yml "excel-handle/ent/yaml"
	"excel-handle/util"
	"fmt"
	"github.com/xuri/excelize/v2"
	"gopkg.in/yaml.v3"
	"os"
	"time"
)

func ReadPropFile(propFilePath string) (yml.Prop, error) {

	// 按指定的路径读取配置文件
	file, err := os.ReadFile(propFilePath)

	if err != nil {
		fmt.Printf("文件读取失败：%v\n", err)
	}

	var data yml.Prop

	// 反序列化（流转为对象）
	err = yaml.Unmarshal(file, &data)
	if err != nil {
		fmt.Printf("无法转为YAML文件: %v", err)
	}

	// 现在data对象包含了YAML文件的数据，可以进行操作了
	// 测试打印读取
	//fmt.Println(data.DailyDuty.MonthFirstThrowRubbishMember)

	return data, err
}

var DefaultExcelTemplatePath = rootDir + "res\\ExcelTemp.xlsx"

var Sheet1 = "Sheet1"

var DestMonth int

func applyExcelStyle(excel *excelize.File) {
	// 创建样式
	// NewStyle函数的参数是一个指向excelize.Style结构体的指针
	//excel.SetDefaultFont("微软雅黑")
	var headStyleId, _ = excel.NewStyle(&HeadStyleDef)
	sheetStyleId, _ := excel.NewStyle(&SheetGlobalStyleDef)

	// 应用样式
	util.ApplyByStyleId(excel, Sheet1, sheetStyleId)
	// 首行标题
	// excel单元格索引以1开始
	excel.SetRowStyle(Sheet1, 1, 1, headStyleId)
}

// 读取配置
func PrepareData(prop yml.Prop) ([]ent.DutyItem, []ent.DutyItem) {

	DestMonth = prop.DailyDuty.Month

	// 读取节假日信息
	fullDays := ReadFullDays()

	dayInfos := make([]json.DayInfoFull, 0)
	// 过滤指定月份
	for _, fullDay := range fullDays {
		// 过滤值获取指定月份
		if fullDay.Month != DestMonth {
			continue
		}
		dayInfos = append(dayInfos, fullDay)
	}
	fullDays = nil

	// 处理prop 进行排序

	members := prop.DailyDuty.Members
	firstThrowRubbishMember := prop.DailyDuty.MonthFirstThrowRubbishMember
	firstOnDutyMember := prop.DailyDuty.MonthFirstDoCleanMember

	// 获取索引
	firstThrowRubbishIndex := GetMemberIndex(members, firstThrowRubbishMember)
	firstOnDutyIndex := GetMemberIndex(members, firstOnDutyMember)

	fmt.Printf("%v月第一位需要丢垃圾的幸运儿是：%v（索引：%v）\n", DestMonth, firstThrowRubbishMember, firstThrowRubbishIndex)

	fmt.Printf("%v月第一位需要搞卫生的幸运儿是：%v（索引：%v）\n", DestMonth, firstOnDutyMember, firstOnDutyIndex)

	// 生成数据
	throwRubbishData := generateThrowRubbgishData(dayInfos, members, firstThrowRubbishIndex)
	cleanData := generateCleanData(dayInfos, members, firstOnDutyIndex)

	return throwRubbishData, cleanData
}

func GetMemberIndex(members []string, member string) int {
	var firstIndex int

	for i, _member := range members {
		if _member == member {
			firstIndex = i
			break
		}
	}
	return firstIndex
}

func generateThrowRubbgishData(dayInfos []json.DayInfoFull, members []string, tarIndex int) []ent.DutyItem {

	var dutyData = []ent.DutyItem{}

	for _, dayInfo := range dayInfos {

		date, _ := time.Parse(SimpleDateLayout, dayInfo.Date)
		// 跳过普通周末
		//if dayInfo.Status == enum.WeekendOffDay.Val() {
		if util.IsWeekend(date) && enum.WorkdayButWeekend.Val() != dayInfo.Status {
			continue
		}

		dateGen := fmt.Sprintf("%v月%v日", dayInfo.Month, dayInfo.Day)

		// 填充非周末的法定节假日
		if dayInfo.Status == enum.LegalHoliday.Val() {
			dutyData = append(dutyData, ent.DutyItem{
				//Date:    fmt.Sprintf("%v\r\n%v", dateGen, dayDesc),
				Date:    dateGen,
				Weekday: util.WeekdayMap[date.Weekday()],
				Name:    "🈚️",
				Comment: dayInfo.StatusDesc,
			})
			continue
		}

		// 值日生 索引取余
		if tarIndex != 0 {
			tarIndex = tarIndex % len(members)
		}

		// 补班日
		if enum.WorkdayButWeekend.Val() == dayInfo.Status {
			dutyData = append(dutyData, ent.DutyItem{
				Date:    dateGen,
				Weekday: util.WeekdayMap[date.Weekday()],
				Name:    members[tarIndex],
				Comment: dayInfo.StatusDesc,
			})
			continue
		}

		// 普通工作日
		dutyData = append(dutyData, ent.DutyItem{
			Date:    dateGen,
			Weekday: util.WeekdayMap[date.Weekday()],
			Name:    members[tarIndex],
		})

		// 索引自增
		tarIndex++
	}

	return dutyData
}

func generateCleanData(dayInfos []json.DayInfoFull, members []string, tarIndex int) []ent.DutyItem {

	var dutyData = []ent.DutyItem{}

	for _, dayInfo := range dayInfos {

		date, _ := time.Parse(SimpleDateLayout, dayInfo.Date)
		// 跳过普通周末
		if util.IsWeekend(date) && enum.WorkdayButWeekend.Val() != dayInfo.Status {
			continue
		}

		dateGen := fmt.Sprintf("%v月%v日", dayInfo.Month, dayInfo.Day)

		// 索引取余
		if tarIndex != 0 {
			tarIndex = tarIndex % len(members)
		}

		// 填充周三周五
		if date.Weekday() == time.Wednesday /*|| date.Weekday() == time.Friday*/ {

			// 周三周五的法定节假日
			if enum.LegalHoliday.Val() == dayInfo.Status {
				dutyData = append(dutyData, ent.DutyItem{
					Date:    dateGen,
					Weekday: util.WeekdayMap[date.Weekday()],
					Name:    "🈚️",
					Comment: dayInfo.StatusDesc,
				})
			} else {
				// 普通工作日
				dutyData = append(dutyData, ent.DutyItem{
					Date:    dateGen,
					Weekday: util.WeekdayMap[date.Weekday()],
					Name:    members[tarIndex],
				})
			}
		} else {
			// 不是周三或周五则不分配搞卫生。
			// 并且跳过自增索引！
			continue
		}

		// 索引自增
		tarIndex++
	}

	return dutyData
}

func FillExcelData(excel *excelize.File, throwRubbishItems []ent.DutyItem, onDutyCleanItems []ent.DutyItem) {

	// 填充丢垃圾
	for i, item := range throwRubbishItems {
		// 数组初始索引为0，单元格初始索引为1。除去标题行，第一行数据为2.
		DateCellName := fmt.Sprintf("A%v", i+2)
		excel.SetCellValue(Sheet1, DateCellName, item.Date)
		WeekdayCellName := fmt.Sprintf("B%v", i+2)
		excel.SetCellValue(Sheet1, WeekdayCellName, item.Weekday)
		MemberCellName := fmt.Sprintf("C%v", i+2)
		excel.SetCellValue(Sheet1, MemberCellName, item.Name)
		CommentCellName := fmt.Sprintf("D%v", i+2)
		excel.SetCellValue(Sheet1, CommentCellName, item.Comment)
	}

	// 填充搞卫生
	for i, item := range onDutyCleanItems {

		// 数组初始索引为0，单元格初始索引为1。除去标题行，第一行数据为2.
		DateCellName := fmt.Sprintf("F%v", i+2)
		excel.SetCellValue(Sheet1, DateCellName, item.Date)
		WeekdayCellName := fmt.Sprintf("G%v", i+2)
		excel.SetCellValue(Sheet1, WeekdayCellName, item.Weekday)
		MemberCellName := fmt.Sprintf("H%v", i+2)
		excel.SetCellValue(Sheet1, MemberCellName, item.Name)
		CommentCellName := fmt.Sprintf("I%v", i+2)
		excel.SetCellValue(Sheet1, CommentCellName, item.Comment)

	}
}
